package com.sunseen.capacitormachine.modules.permission.factory;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.Toast;

import androidx.databinding.ViewDataBinding;
import androidx.recyclerview.widget.LinearLayoutManager;

import com.google.android.material.tabs.TabLayout;
import com.sunseen.capacitormachine.R;
import com.sunseen.capacitormachine.databinding.FragmentExtractLogBinding;
import com.sunseen.capacitormachine.common.BaseFragment;
import com.sunseen.capacitormachine.modules.permission.factory.adapter.LogFileAdapter;
import com.sunseen.capacitormachine.modules.permission.factory.event.LogFileCopyFinish;
import com.sunseen.capacitormachine.modules.permission.factory.event.LogFileScanResult;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class ExtractLogFragment extends BaseFragment {
    @Override
    protected int setLayout() {
        return R.layout.fragment_extract_log;
    }

    private final String normalLogFolderPath = "/sdcard/LogUtils/logs";
    private final String crashLogFolderPath = "/sdcard/crash";

    private boolean deleteLocalFile = false;

    private List<FileCheckBean> normalLogFileList = new ArrayList<>();
    private List<FileCheckBean> crashLogFileList = new ArrayList<>();
    private List<FileCheckBean> selectedFileList = new ArrayList<>();

    private int curTabPos = 0;
    private LogFileAdapter logFileAdapter;

    private Runnable scanFilesRun = new Runnable() {
        @Override
        public void run() {
            File normalLogFile = new File(normalLogFolderPath);
            File[] nLogFiles = null;
            if (normalLogFile.exists()) {
                nLogFiles = normalLogFile.listFiles();
            }
            File crashLogFile = new File(crashLogFolderPath);
            File[] cLogFiles = null;
            if (crashLogFile.exists()) {
                cLogFiles = crashLogFile.listFiles();
            }
            if ((nLogFiles == null || nLogFiles.length == 0) && (cLogFiles == null || cLogFiles.length == 0)) {
                EventBus.getDefault().post(new LogFileScanResult(false));
            } else {
                EventBus.getDefault().post(new LogFileScanResult(true, nLogFiles, cLogFiles));
            }
        }
    };

    @Override
    protected void onBindView(ViewDataBinding viewDataBinding) {
        EventBus.getDefault().register(this);
        FragmentExtractLogBinding binding = (FragmentExtractLogBinding) viewDataBinding;
        binding.tabLogType.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                curTabPos = tab.getPosition();
                if (curTabPos == 0) {
                    logFileAdapter.setNewData(normalLogFileList);
                } else if (curTabPos == 1) {
                    logFileAdapter.setNewData(crashLogFileList);
                }
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });

        binding.btnRefresh.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (checkUdisk()) {
                    new Thread(scanFilesRun).start();
                } else {
                    normalLogFileList.clear();
                    crashLogFileList.clear();
                    Toast.makeText(_mActivity, "未检测到U盘", Toast.LENGTH_SHORT).show();
                    logFileAdapter.setNewData(curTabPos == 0 ? normalLogFileList : crashLogFileList);
                }

            }
        });

        binding.btnStartExtract.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                selectedFileList.clear();
                for (FileCheckBean bean : normalLogFileList) {
                    if (bean.isCheck()) {
                        selectedFileList.add(bean);
                    }
                }
                for (FileCheckBean bean : crashLogFileList) {
                    if (bean.isCheck()) {
                        selectedFileList.add(bean);
                    }
                }
                if (selectedFileList.size() > 0) {
                    if (dialog == null) {
                        initDialog();
                    }
                    dialog.show();
                } else {
                    Toast.makeText(getContext(), "请选择你要提取的文件", Toast.LENGTH_SHORT).show();
                }
            }
        });
        binding.cbCopyDelete.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                deleteLocalFile = isChecked;
            }
        });
        binding.rvLogs.setLayoutManager(new LinearLayoutManager(getContext()));
        logFileAdapter = new LogFileAdapter(R.layout.layout_item_log_file);
        binding.rvLogs.setAdapter(logFileAdapter);
    }


    private AlertDialog dialog;

    private void initDialog() {

        AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
        builder.setTitle(getString(R.string.extract_log))
                .setMessage(R.string.log_extract_confirm_tip)
                .setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    File uDiskLogs = new File(uDiskPath + "/logs");
                                    if (!uDiskLogs.exists()) {
                                        uDiskLogs.mkdir();
                                    }
                                    for (FileCheckBean f : selectedFileList) {
                                        copyFile(f.getFile(), new File(uDiskPath + "/logs/" + f.getFile().getName()), deleteLocalFile);
                                    }
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                                EventBus.getDefault().post(new LogFileCopyFinish());
                            }
                        }).start();
                    }
                })
                .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                    }
                });
        dialog = builder.create();
    }

    // 复制文件
    public static void copyFile(File sourceFile, File targetFile, boolean deleteLocal)
            throws IOException {
        // 新建文件输入流并对它进行缓冲
        FileInputStream input = new FileInputStream(sourceFile);
        BufferedInputStream inBuff = new BufferedInputStream(input);

        // 新建文件输出流并对它进行缓冲
        FileOutputStream output = new FileOutputStream(targetFile);
        BufferedOutputStream outBuff = new BufferedOutputStream(output);

        // 缓冲数组
        byte[] b = new byte[1024 * 5];
        int len;
        while ((len = inBuff.read(b)) != -1) {
            outBuff.write(b, 0, len);
        }
        // 刷新此缓冲的输出流
        outBuff.flush();

        //关闭流
        inBuff.close();
        outBuff.close();
        output.close();
        input.close();
        if (deleteLocal) {
            sourceFile.delete();
        }
    }

    // 复制文件夹
    public static void copyDirectiory(String sourceDir, String targetDir)
            throws IOException {
        // 新建目标目录
        (new File(targetDir)).mkdirs();
        // 获取源文件夹当前下的文件或目录
        File[] file = (new File(sourceDir)).listFiles();
        for (int i = 0; i < file.length; i++) {
            if (file[i].isFile()) {
                // 源文件
                File sourceFile = file[i];
                // 目标文件
                File targetFile = new
                        File(new File(targetDir).getAbsolutePath()
                        + File.separator + file[i].getName());
                copyFile(sourceFile, targetFile, false);
            }
            if (file[i].isDirectory()) {
                // 准备复制的源文件夹
                String dir1 = sourceDir + "/" + file[i].getName();
                // 准备复制的目标文件夹
                String dir2 = targetDir + "/" + file[i].getName();
                copyDirectiory(dir1, dir2);
            }
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onLogFileScanResult(LogFileScanResult event) {
        if (event.isHasFile()) {
            normalLogFileList.clear();
            crashLogFileList.clear();
            selectedFileList.clear();
            File[] normalLogFiles = event.getNormalLogFiles();
            if (normalLogFiles != null && normalLogFiles.length > 0) {
                for (File f : normalLogFiles) {
                    normalLogFileList.add(new FileCheckBean(f));
                }
            }
            File[] crashLogFiles = event.getCrashLogFiles();
            if (crashLogFiles != null && crashLogFiles.length > 0) {
                for (File f : crashLogFiles) {
                    crashLogFileList.add(new FileCheckBean(f));
                }
            }
            logFileAdapter.setNewData(curTabPos == 0 ? normalLogFileList : crashLogFileList);
        } else {
            Toast.makeText(_mActivity, "未扫描到日志文件", Toast.LENGTH_SHORT).show();
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onLogFileCopyFinish(LogFileCopyFinish event) {
        new Thread(scanFilesRun).start();
        Toast.makeText(_mActivity, "日志文件提取完成", Toast.LENGTH_SHORT).show();
    }

    private String uDiskPath = "";

    private boolean checkUdisk() {
        File file = new File(SystemUpdateFragment.UDISK_PATH);
        if (file.exists()) {
            File[] uDiskFiles = file.listFiles();
            if (uDiskFiles.length > 0) {
                uDiskPath = uDiskFiles[0].getAbsolutePath();
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        EventBus.getDefault().unregister(this);
    }
}

